home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1993 / 1 / 02 / schach / sourcecode / zughilfe.c < prev   
Encoding:
C/C++ Source or Header  |  1995-06-01  |  12.3 KB  |  430 lines

  1.  
  2.  /* ZugHilfe.c : allgemeine Zughilfsfunktionen */
  3.  
  4. #include "Adt.h"
  5.  
  6. Feld * Bauer();
  7. Feld * Springer();
  8. Feld * RestFig();
  9.  
  10. Feld feld[ 28 ];
  11.  
  12.  
  13. ZugOK( s, fe1, fe2, sp )
  14.     Figur s[ 9 ][ 9 ];
  15.     Feld fe1, fe2;
  16.     Special sp;
  17. {
  18.     Feld *fe, *fes;
  19.  
  20.      /* mögliche Züge der betroffenen Figur: */
  21.     switch( s[ fe1 >> 4 ][ fe1 & yposmask ] & figmask ) {
  22.     case bauer:     fe = Bauer( s, fe1, sp );   break;
  23.     case springer:  fe = Springer( s, fe1 );    break;
  24.     default:        fe = RestFig( s, fe1, sp ); break;
  25.     }
  26.  
  27.     while( *fe && *fe != fe2 )
  28.         fe ++;
  29.  
  30.     if( *fe == fe2 && RochOK ( s, fe1, fe2, sp ) )
  31.     return 1;
  32.     else
  33.     return 0;
  34. }
  35.  
  36. RochOK( s, fe1, fe2, sp )
  37.     Figur s[ 9 ][ 9 ];
  38.     Feld fe1, fe2;
  39.     Special sp;
  40. {
  41.     int sx, sy, zx, ok;
  42.     Farbe fa;
  43.  
  44.     sx = fe1 >> 4;    sy = fe1 & yposmask;    zx = fe2 >> 4;
  45.     fa = s[ sx ][ sy ]&farbmask;
  46.  
  47.     ok = 1;
  48.     if( ( s[ sx ][ sy ]&figmask ) == koenig )
  49.     if( zx - sx == 2 || sx - zx == 2 ) {    /* dann ist es Rochade */
  50.         if( zx > sx ) {    /* kurz */
  51.         ok &= !IstSchach( s, fa, fe1, sp );
  52.         s[ 5 ][ sy ] = leer;    s[ 6 ][ sy ] = koenig | fa;
  53.         ok &= !IstSchach( s, fa, 6<<4|sy, sp );
  54.         s[ 6 ][ sy ] = leer;    s[ 7 ][ sy ] = koenig | fa;
  55.         ok &= !IstSchach( s, fa, fe2, sp );
  56.         s[ 7 ][ sy ] = leer;    s[ 5 ][ sy ] = koenig | fa;
  57.         return ok;
  58.         } else {        /* lang */
  59.         ok &= !IstSchach( s, fa, fe1, sp );
  60.         s[ 5 ][ sy ] = leer;    s[ 4 ][ sy ] = koenig | fa;
  61.         ok &= !IstSchach( s, fa, 4<<4|sy, sp );
  62.         s[ 4 ][ sy ] = leer;    s[ 3 ][ sy ] = koenig | fa;
  63.         ok &= !IstSchach( s, fa, fe2, sp );
  64.         s[ 3 ][ sy ] = leer;    s[ 5 ][ sy ] = koenig | fa;
  65.         return ok;
  66.         }
  67.     }
  68.  
  69.     return 1;
  70. }
  71.  
  72. Feld * Bauer( s, fe, sp )
  73.     Figur s[ 9 ][ 9 ];
  74.     Feld fe;
  75.     Special sp;
  76. {
  77.     Feld *fes;
  78.     Farbe fa, fas;
  79.     int x, y;
  80.     int dopzug, yp, yps;
  81.  
  82.     fes = feld;
  83.     x = fe >> 4;
  84.     y = fe & yposmask;
  85.     fa = s[ x ][ y ] & farbmask;
  86.     fas = (fa == weiss ? schwarz : weiss);
  87.  
  88.     if( fa == weiss ) {
  89.         if( x!=1 && (s[ x-1 ][ y+1 ]&farbmask) == fas ) {
  90.             *fes = ((x-1)<<4) | (y+1); fes ++; }
  91.         if( s[ x ][ y+1 ] == leer ) {
  92.             *fes = (x<<4) | (y+1); fes ++; }
  93.         if( x!=8 && (s[ x+1 ][ y+1 ]&farbmask) == fas ) {
  94.             *fes = ((x+1)<<4) | (y+1); fes ++; }
  95.         if( y == 2 && s[ x ][ y+1 ] == leer && s[ x ][ y+2 ] == leer ) {
  96.             *fes = (x<<4) | (y+2); fes ++; }
  97.     } else {
  98.         if( x!=8 && (s[ x+1 ][ y-1 ]&farbmask) == fas ) {
  99.             *fes = ((x+1)<<4) | (y-1); fes ++; }
  100.         if( s[ x ][ y-1 ] == leer ) {
  101.             *fes = (x<<4) | (y-1); fes ++; }
  102.         if( x!=1 && (s[ x-1 ][ y-1 ]&farbmask) == fas ) {
  103.             *fes = ((x-1)<<4) | (y-1); fes ++; }
  104.         if( y == 7 && s[ x ][ y-1 ] == leer && s[ x ][ y-2 ] == leer ) {
  105.             *fes = (x<<4) | (y-2); fes ++; }
  106.     }
  107.      /* en-passant - Schlagen: */
  108.     if( dopzug = ( sp & epmask ) ) {
  109.     yp = fa == weiss ? 5 : 4;
  110.     yps = fa == weiss ? 6 : 3;
  111.     if( dopzug >= 2 && x == dopzug-1 && y == yp ) {
  112.         *fes = (dopzug<<4) | yps;    fes ++;
  113.     } else if( dopzug <= 7 && x == dopzug+1 && y == yp ) {
  114.         *fes = (dopzug<<4) | yps;    fes ++;
  115.     }
  116.     }
  117.  
  118.     *fes = 0;
  119.     return( feld );
  120. }
  121.  
  122. Feld * Springer( s, fe )
  123.     Figur s[ 9 ][ 9 ];
  124.     Feld fe;
  125. {
  126.     Feld *fes;
  127.     Farbe fa;
  128.     int x, y;
  129.  
  130.     fes = feld;
  131.     x = fe >> 4;
  132.     y = fe & yposmask;
  133.     fa = s[ x ][ y ] & farbmask;
  134.  
  135.     if( x<=7 && y<=6 && (s[ x+1 ][ y+2 ]&farbmask)!=fa ) {
  136.         *fes = ((x+1)<<4) | (y+2); fes ++; }
  137.     if( x<=6 && y<=7 && (s[ x+2 ][ y+1 ]&farbmask)!=fa ) {
  138.         *fes = ((x+2)<<4) | (y+1); fes ++; }
  139.     if( x<=6 && y>=2 && (s[ x+2 ][ y-1 ]&farbmask)!=fa ) {
  140.         *fes = ((x+2)<<4) | (y-1); fes ++; }
  141.     if( x<=7 && y>=3 && (s[ x+1 ][ y-2 ]&farbmask)!=fa ) {
  142.         *fes = ((x+1)<<4) | (y-2); fes ++; }
  143.     if( x>=2 && y>=3 && (s[ x-1 ][ y-2 ]&farbmask)!=fa ) {
  144.         *fes = ((x-1)<<4) | (y-2); fes ++; }
  145.     if( x>=3 && y>=2 && (s[ x-2 ][ y-1 ]&farbmask)!=fa ) {
  146.         *fes = ((x-2)<<4) | (y-1); fes ++; }
  147.     if( x>=3 && y<=7 && (s[ x-2 ][ y+1 ]&farbmask)!=fa ) {
  148.         *fes = ((x-2)<<4) | (y+1); fes ++; }
  149.     if( x>=2 && y<=6 && (s[ x-1 ][ y+2 ]&farbmask)!=fa ) {
  150.         *fes = ((x-1)<<4) | (y+2); fes ++; }
  151.  
  152.     *fes = 0;
  153.     return( feld );
  154. }
  155.  
  156. Feld * RestFig( s, fe, sp )
  157.     Figur s[ 9 ][ 9 ];
  158.     Feld fe;
  159.     Special sp;
  160. {
  161.     Feld *fes;
  162.     Farbe fa, fas;
  163.     int x, y, flag, i;
  164.     int xmin, xmax, ymin, ymax;
  165.     int yp;
  166.  
  167.     fes = feld;
  168.     x = fe >> 4;
  169.     y = fe & yposmask;
  170.     fa = s[ x ][ y ] & farbmask;
  171.     fas = (fa == weiss ? schwarz : weiss);
  172.  
  173.      /* die Reichweite des Königs ist beschränkt: */
  174.     if( (s[ x ][ y ]&figmask) == koenig ) {
  175.         xmin = x>=2 ? x-1 : x;  xmax = x<=7 ? x+1 : x;
  176.         ymin = y>=2 ? y-1 : y;  ymax = y<=7 ? y+1 : y;
  177.     } else {
  178.         xmin = ymin = 1;        xmax = ymax = 8;
  179.     }
  180.  
  181.     if( (s[ x ][ y ] & figmask) != laeufer ) { /* horiz. u. vert. */
  182.         flag = i = 1;
  183.         while( flag && y+i<=ymax && (s[ x ][ y+i ]&farbmask)!=fa ) {
  184.             flag = (s[ x ][ y+i ]&farbmask) != fas;
  185.             *fes = (x<<4) | (y+i); fes ++; i ++; }
  186.         flag = i = 1;
  187.         while( flag && x+i<=xmax && (s[ x+i ][ y ]&farbmask)!=fa ) {
  188.             flag = (s[ x+i ][ y ]&farbmask) != fas;
  189.             *fes = ((x+i)<<4) | y; fes ++; i ++; }
  190.         flag = i = 1;
  191.         while( flag && y-i>=ymin && (s[ x ][ y-i ]&farbmask)!=fa ) {
  192.             flag = (s[ x ][ y-i ]&farbmask) != fas;
  193.             *fes = (x<<4) | (y-i); fes ++; i ++; }
  194.         flag = i = 1;
  195.         while( flag && x-i>=xmin && (s[ x-i ][ y ]&farbmask)!=fa ) {
  196.             flag = (s[ x-i ][ y ]&farbmask) != fas;
  197.             *fes = ((x-i)<<4) | y; fes ++; i ++; }
  198.     }
  199.     if( (s[ x ][ y ] & figmask) != turm ) { /* diagonal */
  200.         flag = i = 1;
  201.         while( flag && x+i<=xmax && y+i<=ymax && (s[ x+i ][ y+i ]&farbmask)!=fa ) {
  202.             flag = (s[ x+i ][ y+i ]&farbmask) != fas;
  203.             *fes = ((x+i)<<4) | (y+i); fes ++; i ++; }
  204.         flag = i = 1;
  205.         while( flag && x+i<=xmax && y-i>=ymin && (s[ x+i ][ y-i ]&farbmask)!=fa ) {
  206.             flag = (s[ x+i ][ y-i ]&farbmask) != fas;
  207.             *fes = ((x+i)<<4) | (y-i); fes ++; i ++; }
  208.         flag = i = 1;
  209.         while( flag && x-i>=xmin && y-i>=ymin && (s[ x-i ][ y-i ]&farbmask)!=fa ) {
  210.             flag = (s[ x-i ][ y-i ]&farbmask) != fas;
  211.             *fes = ((x-i)<<4) | (y-i); fes ++; i ++; }
  212.         flag = i = 1;
  213.         while( flag && x-i>=xmin && y+i<=ymax && (s[ x-i ][ y+i ]&farbmask)!=fa ) {
  214.             flag = (s[ x-i ][ y+i ]&farbmask) != fas;
  215.             *fes = ((x-i)<<4) | (y+i); fes ++; i ++; }
  216.     }
  217.      /* Rochade: */
  218.     if( ( s[ x ][ y ]&figmask ) == koenig )
  219.     if( ( fa==weiss && sp&wroch ) || ( fa==schwarz && sp&sroch ) ) {
  220.         yp = fa == weiss ? 1 : 8;
  221.         if( (fa==weiss && sp&wkroch) || (fa==schwarz && sp&skroch) ) {
  222.         if( s[ 6 ][ yp ]==leer && s[ 7 ][ yp ]==leer &&
  223.           s[ 8 ][ yp ]==turm|fa ) {
  224.             *fes = 7<<4|yp;    fes ++;
  225.         }
  226.         }
  227.         if( (fa==weiss && sp&wlroch) || (fa==schwarz && sp&slroch) ) {
  228.         if( s[ 2 ][ yp ]==leer && s[ 3 ][ yp ]==leer &&
  229.           s[ 4 ][ yp ]==leer && s[ 1 ][ yp ]==turm|fa ) {
  230.             *fes = 3<<4|yp;    fes ++;
  231.         }
  232.         }
  233.     }
  234.  
  235.     *fes = 0;
  236.     return( feld );
  237. }
  238.  
  239. IstSchach( s, fa, fe, sp )
  240.     Figur s[ 9 ][ 9 ];
  241.     Farbe fa;
  242.     Feld fe;
  243.     Special sp;
  244. {
  245.     Figur fig;
  246.     Farbe fas;
  247.     Feld *fes;
  248.     int i, j, x, y;
  249.  
  250.     if( fe ) {
  251.         x = fe >> 4;    y = fe & yposmask;
  252.     } else
  253.          /* den König finden: */
  254.         for( i=1; i<=8; i++ )
  255.             for( j=1; j<=8; j++ )
  256.                 if( s[ i ][ j ] == (koenig | fa) ) {
  257.                     x = i; y = j; fe = x << 4 | y;
  258.                 }
  259.  
  260.      /* König von einem Bauer bedroht? */
  261.     if( fa == weiss ) {
  262.         if( y <= 6 )
  263.             if( ( x>=2 && s[ x-1 ][ y+1 ] == sbauer ) ||
  264.               ( x<=7 && s[ x+1 ][ y+1 ] == sbauer ) )
  265.                 return( 1 );
  266.     } else
  267.         if( y >= 3 )
  268.             if( ( x<=7 && s[ x+1 ][ y-1 ] == wbauer ) ||
  269.               ( x>=2 && s[ x-1 ][ y-1 ] == wbauer ) )
  270.                 return( 1 );
  271.  
  272.      /* König durch Springer bedroht? */
  273.     fas = ( fa == weiss ) ? schwarz : weiss;
  274.     s[ x ][ y ] = springer | fa;
  275.     fes = Springer( s, fe );
  276.     while( *fes ) {
  277.         if( s[ *fes >> 4 ][ *fes & yposmask ] == (springer | fas) ) {
  278.             s[ x ][ y ] = koenig | fa;
  279.             return( 1 );
  280.         }
  281.         fes ++;
  282.     }
  283.  
  284.      /* Läufer, Turm oder Dame gefährlich? */
  285.     s[ x ][ y ] = laeufer | fa;
  286.     fes = RestFig( s, fe, sp );
  287.     while( *fes ) {
  288.         fig = s[ *fes >> 4 ][ *fes & yposmask ];
  289.         if( fig == (laeufer | fas) || fig == (dame | fas ) ) {
  290.             s[ x ][ y ] = koenig | fa;
  291.             return( 1 );
  292.         }
  293.         fes ++;
  294.     }
  295.     s[ x ][ y ] = turm | fa;
  296.     fes = RestFig( s, fe, sp );
  297.     while( *fes ) {
  298.         fig = s[ *fes >> 4 ][ *fes & yposmask ];
  299.         if( fig == (turm | fas) || fig == (dame | fas ) ) {
  300.             s[ x ][ y ] = koenig | fa;
  301.             return( 1 );
  302.         }
  303.         fes ++;
  304.     }
  305.  
  306.      /* König/König-Annäherung nicht erlaubt: */
  307.     s[ x ][ y ] = koenig | fa;
  308.     fes = RestFig( s, fe, sp );
  309.     while( *fes ) {
  310.         if( s[ *fes >> 4 ][ *fes & yposmask ] == (koenig | fas) )
  311.             return( 1 );
  312.         fes ++;
  313.     }
  314.  
  315.     return( 0 );
  316. }
  317.  
  318. IstMatt( s, fa, sp )
  319.     Figur s[ 9 ][ 9 ];
  320.     Farbe fa;
  321.     Special sp;
  322. {
  323.     int i, j, x, y, ok;
  324.     Feld *fe, fes, fesk[ 28 ], *fek;
  325.     Figur qu, merk;
  326.  
  327.     for( i=1; i<=8; i++ )
  328.         for( j=1; j<=8; j++ )
  329.             if( (s[ i ][ j ] & farbmask) == fa ) {
  330.                 fes = i << 4 | j;
  331.                 switch( s[ i ][ j ] & figmask ) {
  332.                 case bauer:     fe = Bauer( s, fes, sp );   break;
  333.                 case springer:  fe = Springer( s, fes );    break;
  334.                 default:        fe = RestFig( s, fes, sp ); break;
  335.                 }
  336.                 qu = s[ i ][ j ];
  337.                 s[ i ][ j ] = leer;
  338.  
  339.                  /* Züge kopieren, da fe überschrieben wird */
  340.                 fek = fesk;
  341.                 while( *fe ) {
  342.                     *fek = *fe;
  343.                     fek ++;
  344.                     fe ++;
  345.                 }
  346.                 *fek = 0;
  347.                 fek = fesk;
  348.  
  349.                  /* führt ein Zug dieser Figur ins 'nicht-schach'? */
  350.                 while( *fek ) {
  351.                     x = *fek >> 4;   y = *fek & yposmask;
  352.                     merk = s[ x ][ y ];
  353.                     s[ x ][ y ] = qu;
  354.                     if( qu == (koenig | fa ) )
  355.                         ok = !IstSchach( s, fa, *fek, sp );
  356.                     else
  357.                         ok = !IstSchach( s, fa, 0, sp );
  358.                     s[ x ][ y ] = merk;
  359.                     if( ok ) {
  360.                         s[ i ][ j ] = qu;
  361.                         return( 0 );
  362.                     }
  363.                     fek ++;
  364.                 }
  365.                 s[ i ][ j ] = qu;
  366.             }
  367.  
  368.     return( 1 );
  369. }
  370.  
  371. IstPatt( s, fa, sp )
  372.     Figur s[ 9 ][ 9 ];
  373.     Farbe fa;
  374.     Special sp;
  375. {
  376.     Figur merk;
  377.     Feld fes, *fe, fesk[ 28 ], *fek;
  378.     int i, j, xk, yk, zx, zy;
  379.  
  380.     for( i=1; i<=8; i++ )
  381.         for( j=1; j<=8; j++ )
  382.             if( (s[ i ][ j ] & farbmask) == fa )
  383.                 if( s[ i ][ j ] == (koenig | fa) ) {
  384.                     xk = i; yk = j;
  385.                 } else {
  386.                     fes = i << 4 | j;
  387.                     switch( s[ i ][ j ] & figmask ) {
  388.                     case bauer:     fe = Bauer( s, fes, sp );   break;
  389.                     case springer:  fe = Springer( s, fes );    break;
  390.                     default:        fe = RestFig( s, fes, sp ); break;
  391.                     }
  392.                     if( *fe ) /* ein eigener 'nicht-König' kann ziehen */
  393.                         return( 0 );
  394.                 }
  395.  
  396.      /* kann König ins 'nicht-schach' ziehen? */
  397.     fes = xk << 4 | yk;
  398.     fe = RestFig( s, fes, sp );
  399.     if( *fe ) {
  400.  
  401.          /* Züge kopieren, da fe überschrieben wird */
  402.         fek = fesk;
  403.         while( *fe ) {
  404.             *fek = *fe;
  405.             fek ++;
  406.             fe ++;
  407.         }
  408.         *fek = 0;
  409.         fek = fesk;
  410.  
  411.         s[ xk ][ yk ] = leer;
  412.         do {
  413.             zx = *fek >> 4;
  414.             zy = *fek & yposmask;
  415.             merk = s[ zx ][ zy ];
  416.             s[ zx ][ zy ] = koenig | fa;
  417.             if( !IstSchach( s, fa, *fek, sp ) ) {
  418.                 s[ zx ][ zy ] = merk;
  419.                 s[ xk ][ yk ] = koenig | fa;
  420.                 return( 0 );
  421.             }
  422.             s[ zx ][ zy ] = merk;
  423.             fek ++;
  424.         } while( *fek );
  425.         s[ xk ][ yk ] = koenig | fa;
  426.     }
  427.  
  428.     return( 1 );
  429. }
  430.